V.FHIR Server
這是FHIR Server部分的最後一節了,從明天開始就要正式開始進入FUME的部分,
前面幾天提到了驗證,我們來梳理一下驗證到底是什麼。
從FHIR的流程來看大致是這樣的
申請者與受理者中有一個事件導致兩者需要資料交換
受理者定義出了一個標準,在FHIR中稱為實作指引(IG),用來告訴使用者該怎麼用FHIR來提交資料
申請者收到IG的定義,根據這個IG的指示與限制逐步完成申請文件
申請者使用驗證先行確認自己的申請文件是否符合IG的限制與指示,根據驗證器的結果來修改自己的申請文件
申請者提交資料給受理者,完成資料的上傳/交換
驗證器可以說是上傳文件前的最後一道關卡,旨在排除欄位與格式上的錯誤,至於驗證是怎麼樣進行的,
驗證器通過指定package.tgz(IG)文件的內容,裡面可能包含了 StructureDefinition、Parameters, Terminology等Resource,
驗證器將輸入的FHIR文件與這些Resource的Definition、Constraints等屬性比對,最終輸出驗證的結果,
驗證的結果分為以下幾種(severity)
FATAL -> 嚴重錯誤,通常是根本性的底層錯誤,或是格式不匹配
ERROR -> 一般錯誤,經驗證Constraint與填入欄位不合,或是找不到Terminology等問題
這之上的訊息會導致最終驗證結果為Fail,需要找到錯誤原因並修正
這之下的訊息會告知該FHIR Resource在通過驗證後可能的潛在問題,但不影響驗證結果為Success
WARNING -> 警告,雖不導致驗證錯誤但最好能夠修改掉
INFO -> 訊息,一些驗證器的提醒欄位,不會影響驗證結果
一般來說Warning的結果是不太需要注意的,但是原則上能減少盡可能減少,很多時候驗證器的錯誤或警告來自於Terminology的匯入不完整,
另外,IG的定義不明確也會造成驗證結果產生問題,因為不明確的IG規範或讓使用者無法正確的實作提交正確的欄位,
這也是前面會強調IG的設計應該要完備清楚。
以目前官方在推行的特定IG來說,DICOM實驗室有建置了一個線上的驗證器
https://validator.dicom.tw/app/
目前可以驗證事前審查IG, 重大傷病IG, 電子病歷IG與次世代基因定序IG四種,但這是屬於要提交給官方的資料才適用,
一般用途或非官方的IG要怎麼辦呢?
HL7 FHIR本身也有提供一個Validator,但要注意的是,這個Validator目前只提供已註冊在國際IG registry平台的IG驗證,
https://validator.fhir.org/
這個Validator也提供CLI版本可以使用,在各個IG網頁中,你都可以在最上面的橫列中看到驗證教學,
會個別引導使用者匯入IG至CLI並執行驗證程序,
這個Validator的CLI版本可以正常執行出驗證結果,但由於他在執行驗證時會將所有他認為需要的IG,不同層級繼承的IG全數引用匯入,
因此每次驗證動輒花上5分鐘,並不是一個良好的選擇。
另外,有另一個驗證器叫做Inferno,這個validator的特色是能夠上傳package.tgz進行驗證,目前實測上傳驗證結果是正常無誤的
DICOM實驗室的Validator基底也是使用Inferno
https://inferno.healthit.gov/validator/
至於接下來要談論到的FUME,其公司Outburn近期也發表了一個FHIR Validator稱作YAFVA Validator,
基底使用HL7版本的Validator,但減少了讀取package與Terminology所需的時間。
那麼,FHIR Server層面的驗證又是如何,
除了HAPI FHIR之外,Firely有提供Firely FHIR SDK提供開發者使用,其中有包含驗證的部分,可以透過C#實作讀取IG並產生驗證結果,
但因為筆者並沒有使用Firely的服務,因此只概述於此。
HAPI FHIR的方式是先前提到的$validator,當然也能透過HAPI FHIR的JAVA FHIR SDK來執行,
但無一例外會發生Data lost的問題,Chinlin在他的文章中有提到一個可行的解法,筆者並未完整走通這個流程只提供讀者參考
https://hackmd.io/@chinlinblog/rk3dlFCBJl
https://hackmd.io/@chinlinblog/ryEe5tCS1l
簡要的說,就是讓本地的FHIR Server具有TX Server的能力,並且改寫結構讓驗證$validate可以轉介到另外架好的Inferno Validator,
藉以完成驗證程序
大致寫到這邊,FHIR Server的部分就結束,
明天開始正式進入後半段 FUME的部分